package com.sis.main.server.yss;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;

import com.sis.main.client.DataSecurity;

public class YahooSecuritiesService {

	public class KeyStatisticsHandler {
		DataSecurity dataSecurity;
		boolean booleanIsMarketCapFound;
		boolean booleanIsForwardPEFound;
		boolean booleanIsForwardPENextLine;
		boolean booleanIsPEGFound;
		boolean booleanIsROEFound;
		boolean booleanIsQRGFound;
		boolean booleanIsQEGNextLine;
		boolean booleanIsQEGFound;
		boolean booleanIsCRFound;
		boolean booleanIs10VolFound;
		boolean booleanIs3VolFound;
		
		public KeyStatisticsHandler(BufferedReader bufferedreader, DataSecurity dataSecurity) {
			this.dataSecurity = dataSecurity;
			
			String stringInputStream;
			try {
				while ((stringInputStream = bufferedreader.readLine()) != null) {
					System.out.println(stringInputStream);
					if ( ! booleanIsMarketCapFound ){
						getMarketCapitlization(stringInputStream);
					}
					if ( ! booleanIsForwardPEFound && ! booleanIsForwardPENextLine){
						getIsForwardPENextLine(stringInputStream);
						continue;
					}
					if (! booleanIsForwardPEFound && booleanIsForwardPENextLine) {
						getForwardPriceEarnings(stringInputStream);
					}
					if (! booleanIsPEGFound){
						getPriceToEarningsToGrowth(stringInputStream);
					}
					if (! booleanIsROEFound){
						getReturnOnEquity(stringInputStream);
					}
					if (! booleanIsQRGFound){
						this.getQuarterlyRevenueGrowth(stringInputStream);
					}
					if ( ! booleanIsQEGFound && ! booleanIsQEGNextLine){
						getIsQEGNextLine(stringInputStream);
						continue;
					}
					if (! booleanIsQEGFound && booleanIsQEGNextLine) {
						this.getQuarterlyEarningsGrowth(stringInputStream);
					}
					if (! booleanIsCRFound) {
						this.getCurrentRatio(stringInputStream);
					}
					if (! booleanIs10VolFound){
						this.getAvg10DayVolume(stringInputStream);
					}
					if (! booleanIs3VolFound){
						this.getAvg3MonthVolume(stringInputStream);
						if (booleanIs3VolFound){
							break;
						}
					}
				}//end while readline
				bufferedreader.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//end try
		}//end constructor
		
		private void getMarketCapitlization(String stringInputStream){
			try {
			int intBeginIndexMarketCap = stringInputStream.indexOf("Market Cap");	
		    if (intBeginIndexMarketCap != -1) {
		    	/*
		    	 * actual market cap info is another 114 chars further up 
		    	 * stringInputStream
		    	 */
		    	intBeginIndexMarketCap = intBeginIndexMarketCap + 114;
		    	int intEndIndexMarketCap = intBeginIndexMarketCap + 1;
		    	//now search for end char to get market cap substring length
		    	String stringEndChar = "<";	
		    	boolean booleanIsSearchingForEndChar = true;
		    	int intStartIndex = intBeginIndexMarketCap;
		    	while (booleanIsSearchingForEndChar) {
		    		if (stringInputStream.substring(intStartIndex++, intEndIndexMarketCap++).equals(stringEndChar)) {
		    			break; //end char found
		    		}
		    	}
		    	String stringMarketCap = stringInputStream.substring(intBeginIndexMarketCap, intEndIndexMarketCap - 2);
		    	double doubleMarketCap = new Double(stringInputStream.substring(intBeginIndexMarketCap, intEndIndexMarketCap - 3));
		    	String stringNumberType = stringInputStream.substring(intEndIndexMarketCap - 3, intEndIndexMarketCap - 2);
		    	if (stringNumberType.equals("M")){ //then convert to millions
		    		doubleMarketCap = doubleMarketCap * 1000000; 
		    	}else if (stringNumberType.equals("B")){ //then convert to billions
		    		doubleMarketCap = doubleMarketCap * 1000000000;
		    	}else{
					throw new Exception("stringNumberType unknown");
		    	}	
		    	dataSecurity.setMarketCapitalization(doubleMarketCap);
		    	dataSecurity.setMarketCapitalizationString(stringMarketCap);
		    	booleanIsMarketCapFound = true;
		    }//end if (intBeginIndexMarketCap != -1)
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//end try
		}//end getMarketCap()
		
		private void getForwardPriceEarnings(String stringInputStream){
			try {				/*
				 * actual forward pe info is another 111 chars further up 
				 * stringInputStream
				 */
				int intBeginIndexForwardPE = 83;
				int intEndIndexForwardPE = intBeginIndexForwardPE + 1;
				//now search for end char to get forward pe substring length
				String stringEndChar = "<";	
				String stringCurrentChar;
				boolean booleanIsSearchingForEndChar = true;
				int intStartIndex = intBeginIndexForwardPE;
				while (booleanIsSearchingForEndChar) {
					stringCurrentChar = stringInputStream.substring(intStartIndex++, intEndIndexForwardPE++);
					if (stringCurrentChar.equals(stringEndChar)) {
						break; //end char found
					}
				}
				String stringForwardPE = stringInputStream.substring(intBeginIndexForwardPE, intEndIndexForwardPE - 2);
				if (stringForwardPE.substring(0,1).equals("N")) {
					dataSecurity.setForwardPriceEarningsString("N");
				} else {
					dataSecurity.setForwardPriceEarningsString(stringForwardPE);
					float floatForwardPE = new Float(stringInputStream.substring(intBeginIndexForwardPE, intEndIndexForwardPE - 2));
					dataSecurity.setForwardPriceToEarnings(floatForwardPE);
				}
				booleanIsForwardPEFound = true;
				booleanIsForwardPENextLine = false;
    
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//end try
		}//getForwardPriceEarnings()
		
		private void getIsForwardPENextLine(String stringInputStream){
				if (stringInputStream.indexOf("Forward") != -1) {
					booleanIsForwardPENextLine = true;
				}
			
		}//end getIsForwardPENextLine(String stringInputStream)
		
		private void getPriceToEarningsToGrowth(String stringInputStream){
			try {
			int intBeginIndexPEG = stringInputStream.indexOf("PEG Ratio");	
		    if (intBeginIndexPEG != -1) {
		    	/*
		    	 * actual market cap info is another 59 chars further up 
		    	 * stringInputStream
		    	 */
		    	intBeginIndexPEG = intBeginIndexPEG + 59;
		    	int intEndIndexPEG = intBeginIndexPEG + 1;
		    	//now search for end char to get market cap substring length
		    	String stringEndChar = "<";	
		    	boolean booleanIsSearchingForEndChar = true;
		    	int intStartIndex = intBeginIndexPEG;
		    	while (booleanIsSearchingForEndChar) {
		    		if (stringInputStream.substring(intStartIndex++, intEndIndexPEG++).equals(stringEndChar)) {
		    			break; //end char found
		    		}
		    	}
		    	String stringPEG = stringInputStream.substring(intBeginIndexPEG, intEndIndexPEG - 2);
				if (stringPEG.substring(0,1).equals("N")) {
					dataSecurity.setPriceToEarningsToGrowthString("N");
				} else {
					dataSecurity.setForwardPriceEarningsString(stringPEG);
					float floatPEG = new Float(stringInputStream.substring(intBeginIndexPEG, intEndIndexPEG - 2));
			    	dataSecurity.setPriceToEarningsToGrowth(floatPEG);
				}
		    	booleanIsPEGFound = true;
		    }//end if (intBeginIndexMarketCap != -1)
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//end try
		}//end getPriceToEarningsToGrowth()

		private void getReturnOnEquity(String stringInputStream){
			try {
			int intBeginIndexROE = stringInputStream.indexOf("Return on Equity");	
		    if (intBeginIndexROE != -1) {
		    	/*
		    	 * actual market cap info is another 59 chars further up 
		    	 * stringInputStream
		    	 */
		    	intBeginIndexROE = intBeginIndexROE + 56;
		    	int intEndIndexROE = intBeginIndexROE + 1;
		    	//now search for end char to get market cap substring length
		    	String stringEndChar = "<";	
		    	boolean booleanIsSearchingForEndChar = true;
		    	int intStartIndex = intBeginIndexROE;
		    	while (booleanIsSearchingForEndChar) {
		    		if (stringInputStream.substring(intStartIndex++, intEndIndexROE++).equals(stringEndChar)) {
		    			break; //end char found
		    		}
		    	}
		    	String stringROE = stringInputStream.substring(intBeginIndexROE, intEndIndexROE - 2);
				if (stringROE.substring(0,1).equals("N")) {
					dataSecurity.setReturnOnEquityString("N");
				} else {
					dataSecurity.setReturnOnEquityString(stringROE);
					double doubleROE = new Double(stringInputStream.substring(intBeginIndexROE, intEndIndexROE - 3));
			    	dataSecurity.setReturnOnEquity(doubleROE);
				}		    	
		    	booleanIsROEFound = true;
		    }//end if (intBeginIndexROE != -1)
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//end try
		}//end getReturnOnEquity()

		private void getQuarterlyRevenueGrowth(String stringInputStream){
			try {
			int intBeginIndexQRG = stringInputStream.indexOf("Qtrly Revenue Growth");	
		    if (intBeginIndexQRG != -1) {
		    	/*
		    	 * actual market cap info is another 59 chars further up 
		    	 * stringInputStream
		    	 */
		    	intBeginIndexQRG = intBeginIndexQRG + 60;
		    	int intEndIndexQRG = intBeginIndexQRG + 1;
		    	//now search for end char to get market cap substring length
		    	String stringEndChar = "<";	
		    	boolean booleanIsSearchingForEndChar = true;
		    	int intStartIndex = intBeginIndexQRG;
		    	while (booleanIsSearchingForEndChar) {
		    		if (stringInputStream.substring(intStartIndex++, intEndIndexQRG++).equals(stringEndChar)) {
		    			break; //end char found
		    		}
		    	}
		    	String stringQRG = stringInputStream.substring(intBeginIndexQRG, intEndIndexQRG - 2);
				if (stringQRG.substring(0,1).equals("N")) {
					dataSecurity.setQuarterlyRevenueGrowthString("N");
				} else {
					dataSecurity.setQuarterlyRevenueGrowthString(stringQRG);
					double doubleQRG = new Double(stringInputStream.substring(intBeginIndexQRG, intEndIndexQRG - 3));
			    	dataSecurity.setQuarterlyRevenueGrowth(doubleQRG);
				}		    	
		    	booleanIsQRGFound = true;
		    }//end if (intBeginIndexQRG != -1)
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//end try
		}//end getQuarterlyRevenueGrowth()
		
		private void getIsQEGNextLine(String stringInputStream){
			if (stringInputStream.indexOf("Qtrly Earnings Growth") != -1) {
				booleanIsQEGNextLine = true;
			}
		}

		private void getQuarterlyEarningsGrowth(String stringInputStream){
			try {
		    	int intBeginIndexQEG = 12;
		    	int intEndIndexQEG = intBeginIndexQEG + 1;
		    	String stringEndChar = "N";
		    	String stringCurrentChar = stringInputStream.substring(intBeginIndexQEG, intEndIndexQEG);
		    	if (stringCurrentChar.equals(stringEndChar)){
		    		dataSecurity.setQuarterlyEarningsGrowthString("N");
			    	booleanIsQEGFound = true;
			    	booleanIsQEGNextLine = false;
		    		return;
		    	}
		    	//now search for end char to get QEG substring length
		    	int intStartIndex = intBeginIndexQEG;
		    	stringEndChar = "<";	
		    	boolean booleanIsSearchingForEndChar = true;
		    	while (booleanIsSearchingForEndChar) {
		    		if (stringInputStream.substring(intStartIndex++, intEndIndexQEG++).equals(stringEndChar)) {
		    			break; //end char found
		    		}
		    	}
		    	String stringQEG = stringInputStream.substring(intBeginIndexQEG, intEndIndexQEG - 2);
				dataSecurity.setQuarterlyEarningsGrowthString(stringQEG);
				double doubleQEG = new Double(stringInputStream.substring(intBeginIndexQEG, intEndIndexQEG - 3));
		    	dataSecurity.setQuarterlyEarningsGrowth(doubleQEG);
		    	booleanIsQEGFound = true;
		    	booleanIsQEGNextLine = false;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//end try
		}//end getQuarterlyEarniungsGrowth()
		
		private void getCurrentRatio(String stringInputStream){
			try {
			int intBeginIndexCR = stringInputStream.indexOf("Current Ratio");	
		    if (intBeginIndexCR != -1) {
		    	/*
		    	 * actual current ration info is another 53 chars further up 
		    	 * stringInputStream
		    	 */
		    	intBeginIndexCR = intBeginIndexCR + 53;
		    	int intEndIndexCR = intBeginIndexCR + 1;
		    	//now search for end char to get market cap substring length
		    	String stringEndChar = "<";	
		    	boolean booleanIsSearchingForEndChar = true;
		    	int intStartIndex = intBeginIndexCR;
		    	while (booleanIsSearchingForEndChar) {
		    		if (stringInputStream.substring(intStartIndex++, intEndIndexCR++).equals(stringEndChar)) {
		    			break; //end char found
		    		}
		    	}
		    	String stringCR = stringInputStream.substring(intBeginIndexCR, intEndIndexCR - 2);
				if (stringCR.substring(0,1).equals("N")) {
					dataSecurity.setCurrentRatioString("N");
				} else {
					dataSecurity.setCurrentRatioString(stringCR);
					float floatCR = new Float(stringInputStream.substring(intBeginIndexCR, intEndIndexCR - 2));
			    	dataSecurity.setCurrentRatio(floatCR);
				}		    	
		    	booleanIsCRFound = true;
		    }//end if (intBeginIndexCR != -1)
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//end try
		}//end getCurrentRatio()

		private void getAvg10DayVolume(String stringInputStream){
			try {
			int intBeginIndex10Vol = stringInputStream.indexOf("Average Volume (10 day)");	
		    if (intBeginIndex10Vol != -1) {
		    	/*
		    	 * actual market cap info is another 59 chars further up 
		    	 * stringInputStream
		    	 */
		    	intBeginIndex10Vol = intBeginIndex10Vol + 92;
		    	int intEndIndex10Vol = intBeginIndex10Vol + 1;
		    	//now search for end char to get market cap substring length
		    	String stringEndChar = "<";	
		    	boolean booleanIsSearchingForEndChar = true;
		    	int intStartIndex = intBeginIndex10Vol;
		    	String string10VolLong = new String();
		    	boolean booleanIsDecimalPointValue = false;
		    	while (booleanIsSearchingForEndChar) {
		    		String stringCurrentChar = stringInputStream.substring(intStartIndex++, intEndIndex10Vol++);
		    		if (stringCurrentChar.equals(stringEndChar)) {
		    			break; //end char found
		    		} else {
		    			if ( ! stringCurrentChar.equals(",")){
		    				if (stringCurrentChar.equals(".")){
		    					booleanIsDecimalPointValue = true;
		    				}
		    				if ( ! booleanIsDecimalPointValue){
		    					string10VolLong = string10VolLong + stringCurrentChar;		
		    				}
		    			}
		    		}
		    	}//end while (booleanIsSearchingForEndChar)
		    	String string10Vol = stringInputStream.substring(intBeginIndex10Vol, intEndIndex10Vol - 2);
				if (string10Vol.substring(0,1).equals("N")) {
					dataSecurity.setAverage10DayVolumeString("N");
				} else {
					dataSecurity.setAverage10DayVolumeString(string10Vol);
					long long10Vol = new Long(string10VolLong);
			    	dataSecurity.setAverage10DayVolume(long10Vol);
				}		    	
		    	booleanIs10VolFound = true;
		    }//end if (intBeginIndexAvg10Vol != -1)
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//end try
		}//end getAvg10DayVolume()

		private void getAvg3MonthVolume(String stringInputStream){
			try {
			int intBeginIndex3Vol = stringInputStream.indexOf("Average Volume (3 month)");	
		    if (intBeginIndex3Vol != -1) {
		    	/*
		    	 * actual market cap info is another 59 chars further up 
		    	 * stringInputStream
		    	 */
		    	intBeginIndex3Vol = intBeginIndex3Vol + 93;
		    	int intEndIndex3Vol = intBeginIndex3Vol + 1;
		    	//now search for end char to get market cap substring length
		    	String stringEndChar = "<";	
		    	boolean booleanIsSearchingForEndChar = true;
		    	int intStartIndex = intBeginIndex3Vol;
		    	String string3VolLong = new String();
		    	boolean booleanIsDecimalPointValue = false;
		    	while (booleanIsSearchingForEndChar) {
		    		String stringCurrentChar = stringInputStream.substring(intStartIndex++, intEndIndex3Vol++);
		    		if (stringCurrentChar.equals(stringEndChar)) {
		    			break; //end char found
		    		} else {
		    			if ( ! stringCurrentChar.equals(",")){
		    				if (stringCurrentChar.equals(".")){
		    					booleanIsDecimalPointValue = true;
		    				}
		    				if ( ! booleanIsDecimalPointValue){
		    					string3VolLong = string3VolLong + stringCurrentChar;		
		    				}
		    			}
		    		}
		    	}//end while (booleanIsSearchingForEndChar)
		    	String string3Vol = stringInputStream.substring(intBeginIndex3Vol, intEndIndex3Vol - 2);
				if (string3Vol.substring(0,1).equals("N")) {
					dataSecurity.setAverage10DayVolumeString("N");
				} else {
					dataSecurity.setAverage3MonthVolumeString(string3Vol);
					long long3Vol = new Long(string3VolLong);
			    	dataSecurity.setAverage3MonthVolume(long3Vol);
				}		    	
		    	booleanIs3VolFound = true;
		    }//end if (intBeginIndexAvg3Vol != -1)
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//end try
		}//end getAvg3MonthVolume()

		
	}//end class KeyStatisticsHandler
	

	public void getDataKeyStatistics(DataSecurity dataSecurity){
		URL urlKeyStatistics;
		try {
			urlKeyStatistics = new URL("http://finance.yahoo.com/q/ks?s=" 
					+ dataSecurity.getSymbol());
			new KeyStatisticsHandler( 
					new BufferedReader(
							new InputStreamReader(urlKeyStatistics.openStream()))
					, dataSecurity);

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}//end getDataKeyStatistics(DataSecurity dataSecurity)
	
}//end class YahooSecuritiesService
